import { AbstractController, Restful, Router } from '@jingli/restful';
import { Request, Response, NextFunction } from 'express';
import doc from '@jingli/doc';
import { DB } from '../model';
import { NotFoundError, NotPermitError, ParamsNotValidError } from '@jingli/error';
import { JLRequest, JLResponse } from '../types';

@Restful()
export default class ScheduleController extends AbstractController {
    constructor() { 
        super();
    }

    $isValidId(id: string) { 
        return /^\d+$/.test(id);
    }

    @doc("获取日程详情")
    async get(req: JLRequest, res: JLResponse, next: NextFunction) { 
        let { id } = req.params;
        let { uid } = req.session;

        let schedule = await DB.models['Schedule'].findById(id);
        if (!schedule) { 
            throw new NotFoundError('日程');
        }
        if (schedule.uid != uid) { 
            throw new NotPermitError('日程');
        }
        let attributes = await DB.models['ScheduleAttribute'].findAll({
            where: {
                schedule: id,
            }
        });

        schedule = schedule.toJSON();
        schedule.attributes = attributes;
        res.json(this.reply(0, schedule));
    }

    @doc("添加日程")
    async add(req: JLRequest, res: JLResponse, next: NextFunction) { 
        let { title, category, beginTime, endTime, degree, description, attributes} = req.body;
        let { uid } = req.session;
        if (!title) { 
            throw new ParamsNotValidError('title');
        }
        if (!category) { 
            throw new ParamsNotValidError("category");
        }
        let schedule = await DB.models['Schedule'].build({
            title,
            uid,
            category,
            beginTime,
            endTime,
            degree,
            description,
        })
        schedule = await schedule.save();
        if (!attributes) { 
            attributes = [];
        }
        let attrs = await Promise.all(attributes.map(async (attribute: any) => {
            attribute.schedule = schedule.id;
            attribute = DB.models['ScheduleAttribute'].build(attribute);
            return attribute.save();
        }));
        
        let ret = schedule.toJSON();
        ret.attributes = attrs
        res.json(this.reply(0, ret));
    }

    @doc("归档日程")
    @Router('/:id/archive', 'POST')
    async archive(req: JLRequest, res: JLResponse, next: NextFunction) { 
        let { id } = req.params;
        let { uid } = req.session;
        let schedule = await DB.models['Schedule'].findById(id);
        if (!schedule) { 
            throw new NotFoundError('日程');
        }
        if (schedule.uid != uid) { 
            throw new NotPermitError('归档日程');
        }
        schedule.status = -1;
        schedule = await schedule.save();
        res.json(this.reply(0, schedule));
    }

    @doc("日程列表")
    async find(req: JLRequest, res: JLResponse, next: NextFunction) { 
        let { uid } = req.session;
        let { status, limit, degree} = req.query;
        if (!status) { 
            status = 1;
        }
        let where: any = {
            uid,
            status,
        };
        if (degree) { 
            where.degree = degree;
        }
        let schedules = await DB.models['Schedule'].findAll({
            where: where,
            limit: limit,
            order: [["endTime", "asc"]]
        });
        res.json(this.reply(0, schedules));
    }

    @doc("更改日程")
    async update(req: JLRequest, res: JLResponse, next: NextFunction) { 
        let { id } = req.params;
        let { degree, status } = req.body;
        let schedule = await DB.models['Schedule'].findById(id);
        if (degree && schedule.degree != degree) { 
            schedule.degree = degree;
        }
        if (status && schedule.status != status) { 
            schedule.status = status;
        }
        schedule = await schedule.save();
        res.json(this.reply(0, schedule));
    }
}